/*
面向对象：1.找对象 ， 2.调用对象的方法和属性实现效果
   把每个小球当成一个对象 ， 把生成小球和让小球能够动起来的等等代码都封装起来

       封装：
           属性
               半径,颜色,速度,位置
               radius,color,vx,vy,x,y
           方法
               draw(),move()
*/
class Ball {

    /**
     * 球的class的构造函数
     * @param { Number } x  圆心的x坐标
     * @param { Number } y  圆心的y坐标
     * @param { Number } vx x轴方向的速度
     * @param { Number } vy y轴方向的速度
     * @param { Number } radius 圆的半径 
     * @param { String } color 球的颜色 
     */
    constructor(x, y, vx, vy, radius, color) {
        this.x = x
        this.y = y
        this.vx = vx
        this.vy = vy
        this.radius = radius
        this.color = color
    }
    // context作为参数传入，好处是，我们将来如果把代码拿走，也可以正常使用
    draw(context) {
        context.beginPath()
        context.arc(this.x, this.y, this.radius, 0, 2 * Math.PI)
        context.closePath()
        context.fillStyle = this.color
        context.fill()
    }
    // 包含移动和回弹的代码
    move() {
        this.x += this.vx
        this.y += this.vy
        // 判断 到达了边缘没有
        if (this.x <= +this.radius || this.x >= (800 - this.radius)) {
            this.vx *= -1
        }
        if (this.y <= +this.radius || this.y >= (600 - this.radius)) {
            this.vy *= -1
        }
    }
    // 判断是否和别的小球发生了碰撞的方法 , 通过返回true或者false来知道是否和别的小球发生了碰撞
    isCollision(other) { // other是另一个小球
        const dx = this.x - other.x;
        const dy = this.y - other.y;
        const distance = Math.sqrt(dx * dx + dy * dy);
        // 如果 两个圆心之间的距离，小于两个球半径和，就是碰撞了
        if (distance < this.radius + other.radius) {
            return true
        }
        return false
    }
}

/**
 * 随机整数
 * @param { Number } min 随机数最小值 
 * @param { Number } max 随机数最大值
 * @returns Number
 */
function random(min, max) {
    return Math.floor(Math.random() * (max - min)) + min;
}

/**
 * 随机颜色
 * @returns String
 */
function randomColor() {
    return 'rgb(' +
        random(0, 255) + ', ' +
        random(0, 255) + ', ' +
        random(0, 255) + ')';
}


// 要得到一支笔，才能画东西
let cvs = document.getElementById('cvs')
let context = cvs.getContext('2d')

let balls = []
for (let i = 0; i < 40; i++) {
    let ball = new Ball(random(200, 600), random(200, 400), random(-10, 10), random(-10, 10), random(10, 20), randomColor())
    balls.push(ball)
}
setInterval(() => {
    // 为了形成拖尾效果
    context.fillStyle = `rgba(0,0,0,.3)`
    context.fillRect(0, 0, 800, 600)

    balls.forEach(ball => {
        // 移动小球
        ball.move()
        // 把小球再画出来
        ball.draw(context)

        // 判断碰撞修改每个小球的颜色
        balls.forEach(other => {
            // 如果 两个小球是同一个，就不判断
            if (other === ball) return
            if (ball.isCollision(other)) {
                ball.color = other.color = randomColor()
            }
        })

        /*
            for (let i = 0; i < balls.length; i++) {
                // 如果 两个小球是同一个，就不判断
                if (balls[i] === ball) { continue }
                // // 算出 两个圆心之间的距离 -- 勾股定理
                // const dx = ball.x - balls[i].x;
                // const dy = ball.y - balls[i].y;
                // const distance = Math.sqrt(dx * dx + dy * dy);
                // // 如果 两个圆心之间的距离，小于两个球半径和，就是碰撞了
                // if (distance < ball.radius + balls[i].radius) {
                //     ball.color = balls[i].color = randomColor()
                // }

                if (ball.isCollision(balls[i])) {
                    ball.color = balls[i].color = randomColor()
                }
            } 
        */
    })
}, 30);

